package promotion

import (
	sqlc "bp/db/sqlc"
	sharedConv "bp/internal/rpcserver/shared/conv"
	"bp/internal/service/param"
	promotionGrpc "bp/rpc/gen/webapi/promotion"
)

type PromotionPtrEntityToPbFunc func(*sqlc.Promotion) *promotionGrpc.PromotionEntity
type PromotionPtrArrayEntityToPbFunc func([]*sqlc.Promotion) []*promotionGrpc.PromotionEntity

// ConvPromotionPtrEntityToPb get func of *sqlc.Promotion => *promotionGrpc.PromotionEntity
func (s *PromotionWebApiImp) ConvPromotionPtrEntityToPb(
	itemCategoryPtrs param.ItemCategoryConfigurationPtrArray,
	itemPtrs param.ItemConfigurationPtrArray,
) PromotionPtrEntityToPbFunc {
	return func(ptr *sqlc.Promotion) *promotionGrpc.PromotionEntity {
		if ptr == nil {
			return nil
		}
		return &promotionGrpc.PromotionEntity{
			Id:                      ptr.ID,
			OwnerType:               ptr.OwnerType,
			OwnerId:                 ptr.OwnerID,
			Name:                    ptr.Name,
			Desc:                    ptr.Desc.String,
			Tags:                    ptr.Tags,
			Nature:                  ptr.Nature,
			OfferCategory:           ptr.OfferCategory,
			OfferType:               ptr.OfferType,
			Issuer:                  ptr.Issuer,
			PromotionStatus:         ptr.PromotionStatus,
			Published:               sqlc.GoNTimeToPBTimestamp(ptr.Published),
			Paused:                  sqlc.GoNTimeToPBTimestamp(ptr.Paused),
			Resumed:                 sqlc.GoNTimeToPBTimestamp(ptr.Resumed),
			Closed:                  sqlc.GoNTimeToPBTimestamp(ptr.Closed),
			NeedVerifyQualification: ptr.NeedVerifyQualification,
			QualifyTypes:            ptr.QualifyTypes,
			Price:                   ptr.Price,
			Quota:                   ptr.Quota,
			OffMaximum:              ptr.OffMaximum,
			GradientRules:           sharedConv.ConvOffGradientRuleArrayEntityToPb(ptr.GradientRules),
			Begined:                 sqlc.GoTimeToPBTimestamp(ptr.Begined),
			Ended:                   sqlc.GoTimeToPBTimestamp(ptr.Ended),
			TimeRanges:              sharedConv.ConvTimeRangeArrayEntityToPb(ptr.TimeRanges),
			DateChooseType:          ptr.DateChooseType.String,
			Weekdays:                ptr.Weekdays,
			Monthdays:               ptr.Monthdays,
			UseScenes:               ptr.UseScenes,
			Scope:                   ptr.Scope,
			ItemCategoryConfs:       sharedConv.ConvItemCategoryConfigurationPtrArrayEntityToPb(itemCategoryPtrs),
			ItemConfs:               sharedConv.ConvItemConfigurationPtrArrayEntityToPb(itemPtrs),
			ParentId:                ptr.ParentID.Int64,
			CopySource:              ptr.CopySource.Int64,
		}
	}
}

// ConvPromotionPtrArrayEntityToPb get func of []*sqlc.Promotion => []*promotionGrpc.PromotionEntity
func (s *PromotionWebApiImp) ConvPromotionPtrArrayEntityToPb(
	itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap,
	itemMap param.EntityIDToItemConfigurationPtrsMap,
) PromotionPtrArrayEntityToPbFunc {
	return func(ptrs []*sqlc.Promotion) (vPtrs []*promotionGrpc.PromotionEntity) {
		var itemCategoryPtrs param.ItemCategoryConfigurationPtrArray
		var itemPtrs param.ItemConfigurationPtrArray
		for _, ptr := range ptrs {
			if itemCategoryMap != nil {
				itemCategoryPtrs = itemCategoryMap[ptr.ID]
			}
			if itemMap != nil {
				itemPtrs = itemMap[ptr.ID]
			}
			vPtrs = append(vPtrs, s.ConvPromotionPtrEntityToPb(itemCategoryPtrs, itemPtrs)(ptr))
		}
		return
	}
}

type PromotionWithStatPtrEntityToPbFunc func(*sqlc.ListPromotionWithStatsRow) *promotionGrpc.PromotionWithStatEntity
type PromotionWithStatPtrArrayEntityToPbFunc func([]*sqlc.ListPromotionWithStatsRow) []*promotionGrpc.PromotionWithStatEntity

// ConvPromotionPtrEntityToPb get func of *sqlc.ListPromotionWithStatsRow => *promotionGrpc.PromotionWithStatEntity
func (s *PromotionWebApiImp) ConvPromotionWithStatPtrEntityToPb(
	itemCategoryPtrs param.ItemCategoryConfigurationPtrArray,
	itemPtrs param.ItemConfigurationPtrArray,
) PromotionWithStatPtrEntityToPbFunc {
	return func(ptr *sqlc.ListPromotionWithStatsRow) *promotionGrpc.PromotionWithStatEntity {
		if ptr == nil {
			return nil
		}
		return &promotionGrpc.PromotionWithStatEntity{
			Self: &promotionGrpc.PromotionEntity{
				Id:                      ptr.ID,
				OwnerType:               ptr.OwnerType,
				OwnerId:                 ptr.OwnerID,
				Name:                    ptr.Name,
				Desc:                    ptr.Desc.String,
				Tags:                    ptr.Tags,
				Nature:                  ptr.Nature,
				OfferCategory:           ptr.OfferCategory,
				OfferType:               ptr.OfferType,
				Issuer:                  ptr.Issuer,
				PromotionStatus:         ptr.PromotionStatus,
				Published:               sqlc.GoNTimeToPBTimestamp(ptr.Published),
				Paused:                  sqlc.GoNTimeToPBTimestamp(ptr.Paused),
				Resumed:                 sqlc.GoNTimeToPBTimestamp(ptr.Resumed),
				Closed:                  sqlc.GoNTimeToPBTimestamp(ptr.Closed),
				NeedVerifyQualification: ptr.NeedVerifyQualification,
				QualifyTypes:            ptr.QualifyTypes,
				Price:                   ptr.Price,
				Quota:                   ptr.Quota,
				OffMaximum:              ptr.OffMaximum,
				GradientRules:           sharedConv.ConvOffGradientRuleArrayEntityToPb(ptr.GradientRules),
				Begined:                 sqlc.GoTimeToPBTimestamp(ptr.Begined),
				Ended:                   sqlc.GoTimeToPBTimestamp(ptr.Ended),
				TimeRanges:              sharedConv.ConvTimeRangeArrayEntityToPb(ptr.TimeRanges),
				DateChooseType:          ptr.DateChooseType.String,
				Weekdays:                ptr.Weekdays,
				Monthdays:               ptr.Monthdays,
				UseScenes:               ptr.UseScenes,
				Scope:                   ptr.Scope,
				ItemCategoryConfs:       sharedConv.ConvItemCategoryConfigurationPtrArrayEntityToPb(itemCategoryPtrs),
				ItemConfs:               sharedConv.ConvItemConfigurationPtrArrayEntityToPb(itemPtrs),
				ParentId:                ptr.ParentID.Int64,
				CopySource:              ptr.CopySource.Int64,
			},
			Stat: &promotionGrpc.PromotionStatEntity{
				ParticipantCnt:    ptr.ParticipantCnt,
				OffTransCnt:       ptr.OffTransCnt,
				OffAmount:         ptr.OffAmount,
				OffRefundTransCnt: ptr.OffRefundTransCnt,
				OffRefundAmount:   ptr.OffRefundAmount,
			},
		}
	}
}

// ConvPromotionWithStatPtrArrayEntityToPb get func of []*sqlc.ListPromotionWithStatsRow => []*promotionGrpc.PromotionWithStatEntity
func (s *PromotionWebApiImp) ConvPromotionWithStatPtrArrayEntityToPb(
	itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap,
	itemMap param.EntityIDToItemConfigurationPtrsMap,
) PromotionWithStatPtrArrayEntityToPbFunc {
	return func(ptrs []*sqlc.ListPromotionWithStatsRow) (vPtrs []*promotionGrpc.PromotionWithStatEntity) {
		var itemCategoryPtrs param.ItemCategoryConfigurationPtrArray
		var itemPtrs param.ItemConfigurationPtrArray
		for _, ptr := range ptrs {
			if itemCategoryMap != nil {
				itemCategoryPtrs = itemCategoryMap[ptr.ID]
			}
			if itemMap != nil {
				itemPtrs = itemMap[ptr.ID]
			}
			vPtrs = append(vPtrs, s.ConvPromotionWithStatPtrEntityToPb(itemCategoryPtrs, itemPtrs)(ptr))
		}
		return
	}
}
